home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993 October: Windmill on DISC / ADC Developer CD (1993-10) (''Windmill On DISC'')_iso / Dev.CD Oct 93.iso / System Software / U.S. System Software / System 7 Pro™ Beta 11 / Development Tools / Sample Code / Messaging Service Access Module / Internet PMSAM / Internet PMSAM source / spooltoaoce.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-27  |  10.9 KB  |  381 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------
  2.  
  3. AOCE Post Office Protocol (POP) / Simple Mail Transfer Protocol (SMTP)
  4. Mail Service Access Module
  5.  
  6. written by Steve Falkenburg-- MacDTS
  7. ©1991-1993 Apple Computer, Inc.
  8.  
  9. --------------
  10. change history
  11. --------------
  12.  
  13. SJF        02/19/93    update for beta build    b1
  14. SJF        02/19/93    update for beta build    b1
  15. SJF        10/29/92    update to a11            a11
  16. SJF        06/08/92    update to a8            a8
  17. SJF        02/15/92    first working version    a4.5
  18. SJF        10/16/91    initial coding            a3
  19.  
  20. ---------------------------------------------------------------------*/
  21.  
  22. #ifndef __TYPES__
  23. #include <Types.h>
  24. #endif
  25.  
  26. #ifndef __OCE__
  27. #include <OCE.h>
  28. #endif
  29.  
  30. #ifndef __OCEMAIL__
  31. #include <OCEMail.h>
  32. #endif
  33.  
  34. #include <string.h>
  35.  
  36. #include "const.h"
  37. #include "gwerrors.h"
  38. #include "mytypes.h"
  39. #include "globals.h"
  40. #include "utils.h"
  41. #include "spoolsystem.h"
  42. #include "gatewaystuff.h"
  43. #include "spooltoaoce.h"
  44.  
  45. #define    kDefaultSubject            "<no subject>"
  46. #define kDefaultSubjectLength    12
  47. #define    kDefaultBody            "<no message>"
  48. #define kDefaultBodyLength        12
  49.  
  50. #define    kMaxRStringPostIt        kRString32Size-4    // maximum length of sender, subject in postit
  51. #define    kLetterCreator            'lap2'
  52.  
  53.  
  54. // SpoolIntoAOCE
  55. //
  56. // this function is called to retrieve an external message from the spool area and submit
  57. // it into the incoming queue via the toolbox.  it first creates a post-it for the message
  58. // and then creates the actual message and inserts the message data.  if we wanted to be an
  59. // "on-line" gateway, we would just create the post-it and not the message.  we would then get
  60. // a message opened eppc when the user double-clicked and would have to download the message
  61. // in response.
  62. //
  63. OSErr SpoolIntoAOCE(FSSpec *spoolSpec,SlotSpec *slot)
  64. {
  65.     OSErr err;
  66.     MSAMParam gwp;
  67.     unsigned long macSecs;
  68.     MSAMMsgSummary postIt;
  69.     Ptr dataBuffer;
  70.     unsigned long bufferLen;
  71.     unsigned long contentLength;
  72.     RString subject;
  73.     RecordID entitySpecifier;
  74.     DSSpec fromAddress;
  75.     
  76.     MailMsgRef mailRef;
  77.     long msgSeqNum;
  78.     Ptr contentBuffer;
  79.     long contentBufferSize;
  80.     char defaultText[256];
  81.     unsigned char *subjectOffset;
  82.     
  83.     TraceExecution("\pSpoolIntoAOCE");
  84.         
  85.     // allocate buffer for spooling from disk
  86.     
  87.     bufferLen = kMaxBufferSize;
  88.     dataBuffer = NewPtrChk(bufferLen);
  89.     if (MemError()!=noErr)
  90.         return MemError();
  91.  
  92.     
  93.     // get length of message data in bytes (for message summary info)
  94.         
  95.     contentLength = kMaxBufferSize;
  96.     err = GetFromSpool(spoolSpec,kTextContent,kContentCreator,0,dataBuffer,&contentLength,0);
  97.     if (err!=noErr) {
  98.         DisposPtrChk(dataBuffer);
  99.         return err;
  100.     }
  101.     
  102.     // ********** create the post-it (msg summary) for the message **************************
  103.     
  104.     ClearBuffer(&postIt,sizeof(MSAMMsgSummary));
  105.     postIt.version = kMailMsgSummaryVersion;
  106.     postIt.masterData.attrMask.sendTimeStamp = true;
  107.     postIt.masterData.attrMask.indications = true;
  108.     postIt.masterData.attrMask.from = true;
  109.     postIt.masterData.attrMask.subject = true;
  110.     postIt.masterData.attrMask.msgType = true;
  111.     postIt.masterData.attrMask.msgFamily = true;
  112.         
  113.     GetDateTime(&macSecs);                                                            // time
  114.     MacToMailTime(macSecs,&postIt.coreData.sendTime);
  115.     *(long *)&postIt.coreData.letterIndications = 0;
  116.     postIt.coreData.letterIndications.priority = kIPMNormalPriority;                // indications
  117.     postIt.coreData.letterIndications.hasContent = true;
  118.     postIt.coreData.messageType.msgType = kMailLtrMsgType;                            // message type
  119.     postIt.coreData.messageType.msgCreator = kLetterCreator;                        // message creator
  120.     postIt.coreData.messageFamily = kMailFamily;                                    // family of message
  121.     postIt.coreData.messageSize = contentLength;                                    // size of message
  122.     
  123.     // get subject
  124.     
  125.     bufferLen = kRStringMaxBytes;
  126.     err = GetFromSpool(spoolSpec,kSubjectType,kAttribCreator,0,(Ptr)&subject,&bufferLen,0);
  127.     if (err!=noErr)
  128.         OCECToRString(kDefaultSubject,smRoman,(RStringPtr)&subject,kRStringMaxBytes);
  129.     OCECopyFitRString((RStringPtr)&subject,(RStringPtr)&postIt.coreData.subject,kMaxRStringPostIt);
  130.         
  131.     // get from name
  132.     
  133.     bufferLen = kMaxBufferSize;
  134.     err = GetFromSpool(spoolSpec,kFromType,kAddrCreator,0,dataBuffer,&bufferLen,0);
  135.     if (err!=noErr) {
  136.         DisposPtrChk(dataBuffer);
  137.         return err;
  138.     }
  139.     OCEUnpackDSSpec((PackedDSSpec*)dataBuffer,&fromAddress,&entitySpecifier);
  140.     OCECopyFitRString(entitySpecifier.local.recordName,(RStringPtr)&postIt.coreData.sender,kMaxRStringPostIt);
  141.     
  142.     // move subject flush with sender RString (pack them together as close as possible even pad)
  143.     
  144.     subjectOffset = ((unsigned char *)&postIt.coreData.sender)+postIt.coreData.sender.dataLength+sizeof(long);
  145.     if ((unsigned long)subjectOffset % 2)
  146.         subjectOffset++;
  147.     BlockMove(&postIt.coreData.subject,subjectOffset,postIt.coreData.subject.dataLength+sizeof(long));
  148.     
  149.     // make the message summary
  150.     
  151.     gwp.header.ioCompletion = (ProcPtr)MSAMCompletion;
  152.     gwp.pmsamCreateMsgSummary.inQueueRef = slot->inQueue;
  153.     gwp.pmsamCreateMsgSummary.msgSummary = &postIt;
  154.     gwp.pmsamCreateMsgSummary.buffer = nil;
  155.     PMSAMCreateMsgSummary(&gwp,true);
  156.     err = WaitPBDone(&gwp);
  157.     if (err!=noErr) {
  158.         DisposPtrChk(dataBuffer);
  159.         return err;
  160.     }
  161.     msgSeqNum = gwp.pmsamCreateMsgSummary.seqNum;
  162.     
  163.     // ********** create the message (submit the actual data **************************
  164.  
  165.     // first, really create the messsage
  166.     
  167.     gwp.msamCreate.queueRef = slot->inQueue;
  168.     gwp.msamCreate.seqNum = msgSeqNum;
  169.     gwp.msamCreate.asLetter = true;
  170.     gwp.msamCreate.msgType.format = kIPMOSFormatType;
  171.     gwp.msamCreate.msgType.theType.msgOSType.msgCreator = kMailAppleMailCreator;
  172.     gwp.msamCreate.msgType.theType.msgOSType.msgType = kMailLtrMsgType;
  173.     gwp.msamCreate.tunnelForm = false;
  174.     gwp.msamCreate.bccRecipients = false;
  175.     MSAMCreate(&gwp,true);
  176.     err = WaitPBDone(&gwp);
  177.     if (err!=noErr) {
  178.         DisposPtrChk(dataBuffer);
  179.         return err;
  180.     }
  181.     mailRef = gwp.msamCreate.newRef;
  182.     
  183.     // add the time
  184.     
  185.     gwp.msamPutAttribute.mailMsgRef = mailRef;
  186.     gwp.msamPutAttribute.attrID = kMailSendTimeStampBit;
  187.     gwp.msamPutAttribute.buffer.buffer = (Ptr)&postIt.coreData.sendTime;
  188.     gwp.msamPutAttribute.buffer.bufferSize = sizeof(MailTime);
  189.     MSAMPutAttribute(&gwp,true);
  190.     err = WaitPBDone(&gwp);
  191.     if (err!=noErr) {
  192.         BailOnSubmit(mailRef,msgSeqNum,slot->inQueue,dataBuffer);
  193.         return err;
  194.     }
  195.     
  196.     // add the message family
  197.     
  198.     gwp.msamPutAttribute.mailMsgRef = mailRef;
  199.     gwp.msamPutAttribute.attrID = kMailMsgFamilyBit;
  200.     gwp.msamPutAttribute.buffer.buffer = (Ptr)&postIt.coreData.messageFamily;
  201.     gwp.msamPutAttribute.buffer.bufferSize = sizeof(OSType);
  202.     MSAMPutAttribute(&gwp,true);
  203.     err = WaitPBDone(&gwp);
  204.     if (err!=noErr) {
  205.         BailOnSubmit(mailRef,msgSeqNum,slot->inQueue,dataBuffer);
  206.         return err;
  207.     }
  208.  
  209.     // add the indications
  210.     
  211.     gwp.msamPutAttribute.mailMsgRef = mailRef;
  212.     gwp.msamPutAttribute.attrID = kMailIndicationsBit;
  213.     gwp.msamPutAttribute.buffer.buffer = (Ptr)&postIt.coreData.letterIndications;
  214.     gwp.msamPutAttribute.buffer.bufferSize = sizeof(MailIndications);
  215.     MSAMPutAttribute(&gwp,true);
  216.     err = WaitPBDone(&gwp);
  217.     if (err!=noErr) {
  218.         BailOnSubmit(mailRef,msgSeqNum,slot->inQueue,dataBuffer);
  219.         return err;
  220.     }
  221.     
  222.     // add the recipients
  223.     
  224.     err = AddTheRecipients(mailRef,spoolSpec,kFromType,kMailFromBit,dataBuffer,kMaxBufferSize);
  225.     if (err!=noErr) {
  226.         BailOnSubmit(mailRef,msgSeqNum,slot->inQueue,dataBuffer);
  227.         return err;
  228.     }
  229.  
  230.     err = AddTheRecipients(mailRef,spoolSpec,kToType,kMailToBit,dataBuffer,kMaxBufferSize);
  231.     if (err!=noErr) {
  232.         BailOnSubmit(mailRef,msgSeqNum,slot->inQueue,dataBuffer);
  233.         return err;
  234.     }
  235.         
  236.     err = AddTheRecipients(mailRef,spoolSpec,kCCType,kMailCcBit,dataBuffer,kMaxBufferSize);
  237.     if (err!=noErr) {
  238.         BailOnSubmit(mailRef,msgSeqNum,slot->inQueue,dataBuffer);
  239.         return err;
  240.     }
  241.     
  242.     err = AddTheRecipients(mailRef,spoolSpec,kBCCType,kMailBccBit,dataBuffer,kMaxBufferSize);
  243.     if (err!=noErr) {
  244.         BailOnSubmit(mailRef,msgSeqNum,slot->inQueue,dataBuffer);
  245.         return err;
  246.     }
  247.  
  248.     // add the subject
  249.     
  250.     gwp.msamPutAttribute.mailMsgRef = mailRef;
  251.     gwp.msamPutAttribute.attrID = kMailSubjectBit;
  252.     gwp.msamPutAttribute.buffer.buffer = (Ptr)&subject;
  253.     gwp.msamPutAttribute.buffer.bufferSize = subject.dataLength+4;
  254.     if ((gwp.msamPutAttribute.buffer.bufferSize%2)!=0)
  255.         gwp.msamPutAttribute.buffer.bufferSize++;
  256.     MSAMPutAttribute(&gwp,true);
  257.     err = WaitPBDone(&gwp);
  258.     if (err!=noErr) {
  259.         BailOnSubmit(mailRef,msgSeqNum,slot->inQueue,dataBuffer);
  260.         return err;
  261.     }
  262.  
  263.     // add content
  264.     
  265.     bufferLen = kMaxBufferSize;
  266.     err = GetFromSpool(spoolSpec,kTextContent,kContentCreator,0,dataBuffer,&bufferLen,0);
  267.     if (err==noErr) {
  268.         contentBuffer = dataBuffer;
  269.         contentBufferSize = bufferLen;
  270.     }
  271.     else {
  272.         strcpy(defaultText,kDefaultBody);
  273.         contentBuffer = defaultText;
  274.         contentBufferSize = strlen(defaultText);
  275.     }
  276.  
  277.     gwp.msamPutContent.mailMsgRef = mailRef;
  278.     gwp.msamPutContent.segmentType = kMailTextSegmentType;
  279.     gwp.msamPutContent.append = false;
  280.     gwp.msamPutContent.textScrap = nil;
  281.     gwp.msamPutContent.startNewScript = true;
  282.     gwp.msamPutContent.script = smRoman;
  283.     gwp.msamPutContent.buffer.buffer = contentBuffer;
  284.     gwp.msamPutContent.buffer.bufferSize = contentBufferSize;
  285.     MSAMPutContent(&gwp,true);
  286.     err = WaitPBDone(&gwp);
  287.     if (err!=noErr) {
  288.         BailOnSubmit(mailRef,msgSeqNum,slot->inQueue,dataBuffer);
  289.         return err;
  290.     }
  291.  
  292.     // submit the letter
  293.     
  294.     gwp.msamSubmit.mailMsgRef = mailRef;
  295.     gwp.msamSubmit.submitFlag = true;    // submit letter
  296.     err = MSAMSubmit(&gwp);
  297.         
  298.     DisposPtrChk(dataBuffer);
  299.  
  300.     if (err!=noErr) {
  301.         /* delete post-it */
  302.         
  303.         gwp.header.ioCompletion = (ProcPtr)MSAMCompletion;                    
  304.         gwp.msamDelete.queueRef  = slot->inQueue;
  305.         gwp.msamDelete.seqNum = msgSeqNum;
  306.         gwp.msamDelete.msgOnly = false;
  307.         gwp.msamDelete.result = noErr;    // server gw only
  308.         MSAMDelete(&gwp,true);
  309.         WaitPBDone(&gwp);
  310.     }
  311.  
  312.     return err;
  313. }
  314.  
  315.  
  316. void BailOnSubmit(MailMsgRef mailRef,long seqNum,MSAMQueueRef queueRef,Ptr dataBuffer)
  317. {
  318.     MSAMParam gwp;
  319.  
  320.     TraceExecution("\pbail out");
  321.  
  322.     /* delete message */
  323.     
  324.     DisposPtrChk(dataBuffer);
  325.     gwp.msamSubmit.mailMsgRef = mailRef;
  326.     gwp.msamSubmit.submitFlag = false;        // abort letter
  327.     MSAMSubmit(&gwp);
  328.     
  329.     /* delete post-it */
  330.     
  331.     gwp.header.ioCompletion = (ProcPtr)MSAMCompletion;                    
  332.     gwp.msamDelete.queueRef  = queueRef;
  333.     gwp.msamDelete.seqNum = seqNum;
  334.     gwp.msamDelete.msgOnly = false;
  335.     gwp.msamDelete.result = noErr;    // server gw only
  336.     MSAMDelete(&gwp,true);
  337.     WaitPBDone(&gwp);
  338. }
  339.  
  340.  
  341. OSErr AddTheRecipients(MailMsgRef mailRef,FSSpec *spoolSpec,OSType recipType,MailAttributeID attrID,Ptr dataBuffer,unsigned long bufferLen)
  342. {
  343.     OSErr err;
  344.     Boolean moreRecipients = true;
  345.     short index;
  346.     unsigned long gotLength;
  347.     DSSpec recipient;
  348.     RecordID entitySpecifier;
  349.     MSAMParam gwp;
  350.     
  351.     index = 0;
  352.     
  353.     do {
  354.         
  355.         gotLength = bufferLen;
  356.         err = GetFromSpool(spoolSpec,recipType,kAddrCreator,index,dataBuffer,&gotLength,0);
  357.         if (err==noErr && gotLength>0) {
  358.             
  359.             // submit one recipient
  360.             
  361.             OCEUnpackDSSpec((PackedDSSpec*)dataBuffer,&recipient,&entitySpecifier);
  362.             gwp.msamPutRecipient.ioCompletion = (ProcPtr)MSAMCompletion;
  363.             gwp.msamPutRecipient.mailMsgRef = mailRef;
  364.             gwp.msamPutRecipient.attrID = attrID;
  365.             gwp.msamPutRecipient.recipient = &recipient;
  366.             gwp.msamPutRecipient.responsible = false;
  367.             MSAMPutRecipient(&gwp,true);
  368.             err = WaitPBDone(&gwp);
  369.  
  370.         }
  371.         else {
  372.             moreRecipients = false;
  373.             err = noErr;
  374.         }
  375.         
  376.         index++;
  377.     } while (err==noErr && moreRecipients);
  378.     
  379.     return err;
  380. }
  381.